package cn.patient.pp.module.patients.dal.mysql.patients;

import cn.hutool.core.collection.CollUtil;
import cn.patient.pp.framework.common.pojo.PageResult;
import cn.patient.pp.framework.mybatis.core.mapper.BaseMapperX;
import cn.patient.pp.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.patient.pp.module.patients.controller.admin.vo.*;
import cn.patient.pp.module.patients.controller.admin.vo.importExecl.FollowUpExcelVO;
import cn.patient.pp.module.patients.dal.dataobject.patients.FollowUpDO;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;
import java.util.Map;

/**
 * 随访列表 Mapper
 *
 * @author sailv
 */
@Mapper
public interface FollowUpMapper extends BaseMapperX<FollowUpDO> {

    default PageResult<FollowUpDO> selectPage(FollowUpPageReqVO reqVO, List<Long> deptIds) {
        LambdaQueryWrapperX<FollowUpDO> queryWrapperX = new LambdaQueryWrapperX<>();
        queryWrapperX.eqIfPresent(FollowUpDO::getPatientCode, reqVO.getPatientCode())
                .betweenIfPresent(FollowUpDO::getFollowUpDate, reqVO.getFollowUpDate())
                .eqIfPresent(FollowUpDO::getFollowUpMode, reqVO.getFollowUpMode())
                .eqIfPresent(FollowUpDO::getFollowUpTarget, reqVO.getFollowUpTarget())
                .eqIfPresent(FollowUpDO::getFaceToFaceMode, reqVO.getFaceToFaceMode())
                .eqIfPresent(FollowUpDO::getLostContactReason, reqVO.getLostContactReason())
                .eqIfPresent(FollowUpDO::getHospitalizationStatusBetween, reqVO.getHospitalizationStatusBetween())
                .betweenIfPresent(FollowUpDO::getLastDischargeDate, reqVO.getLastDischargeDate())
                .eqIfPresent(FollowUpDO::getRiskAssessment, reqVO.getRiskAssessment())
                .eqIfPresent(FollowUpDO::getCurrentSymptoms, reqVO.getCurrentSymptoms())
                .eqIfPresent(FollowUpDO::getCurrentSymptomsDetail, reqVO.getCurrentSymptomsDetail())
                .eqIfPresent(FollowUpDO::getInsight, reqVO.getInsight())
                .eqIfPresent(FollowUpDO::getSleepCondition, reqVO.getSleepCondition())
                .eqIfPresent(FollowUpDO::getEatingCondition, reqVO.getEatingCondition())
                .eqIfPresent(FollowUpDO::getSelfCare, reqVO.getSelfCare())
                .eqIfPresent(FollowUpDO::getHouseholdTasks, reqVO.getHouseholdTasks())
                .eqIfPresent(FollowUpDO::getWorkStatus, reqVO.getWorkStatus())
                .eqIfPresent(FollowUpDO::getLearningAbility, reqVO.getLearningAbility())
                .eqIfPresent(FollowUpDO::getSocialInteraction, reqVO.getSocialInteraction())
                .eqIfPresent(FollowUpDO::getDangerousBehaviorsFlag, reqVO.getDangerousBehaviorsFlag())
                .eqIfPresent(FollowUpDO::getMinorNuisanceCount, reqVO.getMinorNuisanceCount())
                .eqIfPresent(FollowUpDO::getIncidentCount, reqVO.getIncidentCount())
                .eqIfPresent(FollowUpDO::getHarmfulIncidentCount, reqVO.getHarmfulIncidentCount())
                .eqIfPresent(FollowUpDO::getOtherDangerousBehaviorCount, reqVO.getOtherDangerousBehaviorCount())
                .eqIfPresent(FollowUpDO::getSelfInjuryCount, reqVO.getSelfInjuryCount())
                .eqIfPresent(FollowUpDO::getSuicideAttemptCount, reqVO.getSuicideAttemptCount())
                .eqIfPresent(FollowUpDO::getSeclusionStatus, reqVO.getSeclusionStatus())
                .eqIfPresent(FollowUpDO::getMedicationAdherence, reqVO.getMedicationAdherence())
                .eqIfPresent(FollowUpDO::getReasonNotTakingMedication, reqVO.getReasonNotTakingMedication())
                .eqIfPresent(FollowUpDO::getDoctor, reqVO.getDoctor())
                .eqIfPresent(FollowUpDO::getHospital, reqVO.getHospital())
                .eqIfPresent(FollowUpDO::getAdverseDrugReactions, reqVO.getAdverseDrugReactions())
                .eqIfPresent(FollowUpDO::getTreatmentEffect, reqVO.getTreatmentEffect())
                .eqIfPresent(FollowUpDO::getReferralFlag, reqVO.getReferralFlag())
                .eqIfPresent(FollowUpDO::getReferralReason, reqVO.getReferralReason())
                .eqIfPresent(FollowUpDO::getReferralDestination, reqVO.getReferralDestination())
                .eqIfPresent(FollowUpDO::getRehabilitationMeasures, reqVO.getRehabilitationMeasures())
                .eqIfPresent(FollowUpDO::getCaseManagementFlag, reqVO.getCaseManagementFlag())
                .betweenIfPresent(FollowUpDO::getNextFollowUpDate, reqVO.getNextFollowUpDate())
                .eqIfPresent(FollowUpDO::getIdNumber, reqVO.getIdNumber())
                .inIfPresent(FollowUpDO::getDeptId, reqVO.getDeptIds())
                .eqIfPresent(FollowUpDO::getPatientName, reqVO.getPatientName())
                .eqIfPresent(FollowUpDO::getIdNumber, reqVO.getIdNumber())
                .eqIfPresent(FollowUpDO::getIdNumberType, reqVO.getIdNumberType())
                .eqIfPresent(FollowUpDO::getGender, reqVO.getGender())
                .inIfPresent(FollowUpDO::getDeptId, deptIds)
                .eqIfPresent(FollowUpDO::getCurrentFollowupType, reqVO.getCurrentFollowupType())
                .eqIfPresent(FollowUpDO::getCurrentOrgSubDbStatus, reqVO.getCurrentOrgSubDbStatus()
                );

//        if (hasPoliceRole) {
//            queryWrapperX.in(FollowUpDO::getRiskAssessment, "3", "4", "5");
//        }

        return selectPage(reqVO, queryWrapperX);
    }

    default int deleteAll(List<String> patientCodes) {
        if (CollUtil.isEmpty(patientCodes)) {
            return 0;
        }
        return delete(new MPJLambdaWrapper<FollowUpDO>()
                .in(FollowUpDO::getPatientCode, patientCodes));
    }

    List<FollowUpDO> selectLatestByPatient(@Param("cutoffDate") String cutoffDate);

    /**
     * 分页查询报警数据
     * 
     * @param cutoff7 7天后日期
     * @param cutoff15 15天后日期
     * @param pageNo 页码
     * @param pageSize 每页条数
     * @return 报警数据列表
     */
    List<FollowUpDO> selectAlarmByPage(@Param("nowDate") String nowDate,
                                    @Param("cutoff7") String cutoff7,
                                  @Param("cutoff15") String cutoff15,
                                  @Param("pageNo") Integer pageNo, 
                                  @Param("pageSize") Integer pageSize, @Param("deptIds") List<Long> deptIds,
                                  @Param("managementOrgName") String deptName, @Param("patientName") String patientName,
                                  @Param("idNumber") String idNumber);

    
    /**
     * 获取符合报警条件的记录总数
     * 
     * @param cutoff7 7天后日期（用于判断高风险超期）
     * @param cutoff15 15天后日期（用于判断高风险未随访）
     * @return 报警数据总数
     */
    Long countAlarm(@Param("nowDate") String nowDate,
                    @Param("cutoff7") String cutoff7,
                    @Param("cutoff15") String cutoff15,
                    @Param("deptIds") List<Long> deptIds,
                    @Param("managementOrgName") String deptName, @Param("patientName") String patientName,
                    @Param("idNumber") String idNumber);
    List<increaseAlarmVo> getIncreaseAlarm(NewCheckAlarmReqVO reqVO);
    List<String> selectExistFiveInOneIdNumbers(List<String> idNumbers);
    Long getIncreaseAlarmTotal(NewCheckAlarmReqVO reqVO);
    void insertIgnoreBatch(@Param("list") List<FollowUpExcelVO> list);
    void insertUpdateBatch(@Param("list") List<FollowUpExcelVO> list);

    int selectTotalLatestFollowUps(
            @Param("deptIds") List<Long> deptIds,
            @Param("startStr") String startStr,
            @Param("endStr") String endStr
    );

    int selectFaceLatestFollowUps(
            @Param("deptIds") List<Long> deptIds,
            @Param("startStr") String startStr,
            @Param("endStr") String endStr
    );

    /**
     * 每个 id_number 在 startStr 之前的最新一条随访
     */
    List<LostContactVO> selectLostBeforeStart(
            @Param("deptIds") List<Long> deptIds,
            @Param("startStr") String startStr
    );

    /**
     * 在 startStr 到 endStr 之间的所有随访
     */
    List<LostContactVO> selectLostBetween(
            @Param("deptIds") List<Long> deptIds,
            @Param("startStr") String startStr,
            @Param("endStr")   String endStr
    );

    List<DataComparisonRespVO> selectDataComparison(
            @Param("start")   String start,
            @Param("end")     String end
    );

    Long selectTotalByOrgSubDbStatus(Map<String, Object> params);

    List<PatientTypeCountVO> selectOrgSubDbStatusCounts(Map<String, Object> params);

    DangerBehaviorStatsVO selectDangerBehaviorStats(Map<String, Object> params);

    List<FollowUpDO> getHighRiskPatients(Map<String, Object> params);

    void createTmpDeptTable();

    void batchInsertDeptIds(@Param("deptIds") List<Long> deptIds);

    void dropTmpDeptTable();

}